using NatCamU.Core;
using NatCamU.Core.UI;
using OpenCVForUnity;
using UnityEngine;
using UnityEngine.UI;
using scaleMode = NatCamU.Core.ScaleMode;
using cvRect = OpenCVForUnity.Rect;
using System;
using UnityEngine.SceneManagement;

namespace Argar.Camera.Example
{

    public class MatHelperDemo : MonoBehaviour
    {
        [Header("UI Component")]
        public NatCamPreview preview;
        public NatCamPreview capturePreview;
        public Text textCount;
        private InputField inputMaxFeatures;
        public GameObject Pattam;

        //public Animator Eitbut;

        [Header("Editable Parameter")]
        /// <summary>
        /// 最多可以侦测到的特征点个数
        /// </summary>
        public int maxFeatures = 1000;

        /// <summary>
        /// 当前最大特征点数
        /// </summary>
        private int currentFeatures;

        /// <summary>
        /// 多少帧检测一次特征点
        /// 与FrameRate也有关系
        /// </summary>
        public int detectFrames = 10;

        [Header("Next Scene")]
        /// <summary>
        /// 跳转的场景名
        /// </summary>
        //public string nextScene = "PatternDetect";

        /// <summary>
        /// 获取Mat的快捷接口
        /// </summary>
        private AdvancedNatcamToMatHelper matHelper;

        /// <summary>
        /// 存放预览使用的Texture
        /// </summary>
        private Texture2D patternTexture;

        /// <summary>
        /// 用于特征点识别
        /// </summary>
        private ORB detector;
        private MatOfKeyPoint keypoints;

        /// <summary>
        /// 当前已经流逝的帧数
        /// </summary>
        private int passedFrames = 0;


        // Use this for initialization
        void Start()
        {

            Pattam.SetActive(false);
            //Eitbut = GetComponent<Animator>();

            matHelper = GetComponent<AdvancedNatcamToMatHelper>();
            matHelper.Init();

            detector = ORB.create();
            detector.setMaxFeatures(maxFeatures);
            currentFeatures = maxFeatures;
            keypoints = new MatOfKeyPoint();
        }

        private void Update()
        {
            if (Input.GetKeyUp(KeyCode.Escape))
            {
                matHelper.Stop();
                AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
                jo.Call("Finish");
            }
        }

        public void OnStartCallBack()
        {
            setPreview(NatCam.Preview);
        }

        public void OnFrameCallBack()
        {
            if (NatCam.IsPlaying && matHelper.GetMat() != null)
            {
                if(passedFrames < detectFrames)
                {
                    ++passedFrames;
                    return;
                }

                //init operation
                Mat mat = matHelper.GetMat();

                //根据MaxFeatures是否改变设置最大特征点数
                if (currentFeatures != maxFeatures)
                {
                    detector.setMaxFeatures(maxFeatures);
                    currentFeatures = maxFeatures;
                }

                //do Mat Operation
                detector.detect(mat, keypoints);

                textCount.text = "Detect Points:\n" + keypoints.total();

                //每次侦测完必须重置passedFrames
                passedFrames = 0;
            }
        }

        public void OnDisposeCallBack()
        {
            Texture2D.Destroy(patternTexture);
            keypoints.Dispose();
            detector.Dispose();
        }

        public void setPreview(Texture texture, Orientation orientation = Orientation.Rotation_0, scaleMode mode = scaleMode.FillView)
        {
            preview.Apply(texture,
                orientation,
                mode);
        }

        /// <summary>
        /// 最大特征点改变事件
        /// </summary>
        public void OnMaxFeaturesChanged()
        {
            int temp;
            bool result = int.TryParse(inputMaxFeatures.text, out temp);
            if (result && temp != maxFeatures)
            {
                maxFeatures = temp;
            }
        }

        /// <summary>
        /// 图片保存事件
        /// </summary>
        public void OnSaveButton()
        { 
            if (patternTexture != null)
            {
                Mat saveMat = new Mat(patternTexture.height, patternTexture.width, CvType.CV_8UC3);
                Utils.texture2DToMat(patternTexture, saveMat);
                Imgproc.cvtColor(saveMat, saveMat, Imgproc.COLOR_RGB2BGR);

                string savePath = Application.persistentDataPath;
                Debug.Log("savePath: " + savePath);

                Imgcodecs.imwrite(savePath + "/outputImg.jpg", saveMat);

                saveMat.Dispose();
                saveMat = null;

                //Eitbut.SetBool("kaiguan", true);
                matHelper.Stop();

                Pattam.SetActive(true);
                this.gameObject.SetActive(false);
                //SceneManager.LoadScene(nextScene);
            }
            
        }

        /// <summary>
        /// 屏幕捕捉事件
        /// </summary>
        public void OnCaptureButton()
        {
            NatCam.CapturePhoto(OnPhoto);
        }

        private void OnPhoto(Texture2D photo, Orientation orientation)
        {
            Debug.Log("Photo format: " + photo.format + ", width: " + photo.width + ", height: " + photo.height);
            Mat captureMat = new Mat(photo.height, photo.width, CvType.CV_8UC3);
            Utils.texture2DToMat(photo, captureMat);

            //获取图像中央的正方形作为图案
            int rectWidth = (int)(Mathf.Min(captureMat.width(), captureMat.height()) * 0.6f);
            cvRect patternRect = new cvRect(captureMat.width() / 2 - rectWidth / 2, captureMat.height() / 2 - rectWidth / 2, rectWidth, rectWidth);

            //再次转化为Texture作为预览图
            Mat patternMat = new Mat(captureMat, patternRect);
            patternTexture = patternTexture ?? new Texture2D(patternMat.width(), patternMat.height(), TextureFormat.RGBA32, false);
            Utils.matToTexture2D(patternMat, patternTexture);

            capturePreview.Apply(patternTexture, orientation);

            //释放资源, 因为Mat和Texture占用的资源不会自动释放
            captureMat.Dispose();
            captureMat = null;
            patternMat.Dispose();
            captureMat = null;
            Texture2D.Destroy(photo);
        }


    }

}
